//这里边相当于请求的工具，用来定制请求的实例

//导入axios npm install axios
import axios from 'axios';

//导入Message消息提示
import { ElMessage } from 'element-plus';

//定义一个变量，记录公共的前缀，baseURL
// const baseURL = 'http://localhost:8080';
// 这里的'/api'只是给后台访问的请求路径添加一个标识
const baseURL = '/api';
/*  axios.create()方法，把baseURL作为参数传入，
    该方法返回一个请求的实例instance,
    以后发送请求时，就不用axios.get了，
    直接用instance.get就可以 */
const instance = axios.create({ baseURL })
// const instance = axios.create({
//     baseURL,
//     headers: {
//         'Content-Type': 'application/json',
//         // 可以根据需要添加其他通用请求头，如:
//         // 'Accept': 'application/json'
//     }
// })

/* axios提供的拦截器,
    在请求或响应，被then或catch处理前拦截
    也就是在请求发出之前，有一个请求拦截器
    或在响应到达之前，有一个响应拦截器 */


//导入Pinia
import { useTokenStore } from '@/stores/token';
//添加请求拦截器
instance.interceptors.request.use(
    (config) => {
        //请求前的回调
        const tokenStore = useTokenStore();
        //在pinia中定义的响应式数据,都不需要.value
        if (tokenStore.token) {
            config.headers.Authorization = tokenStore.token;
        }
        return config
    },
    (err) => {
        //请求错误的回调
        Promise.reject(err);
    }
)

/* 由于模块加载的顺序，在request.js里，不能这样导入
    import { useRoute } from 'vue-router';
    const router = useRoute(); 
*/
//这样导入就能用了
import router from '@/router'

//添加响应拦截器(这个拦截器本身就是异步的)
instance.interceptors.response.use(
    //成功的回调
    result => {
        const response = result.data;

        // 定义成功的业务状态码范围
        const successCodes = [0, 200];

        //判断业务状态码
        if (successCodes.includes(response.code)) {
            console.log(result.data);
            return result.data;
        }

        // 特别处理未登录情况（当业务码明确表示未认证时）
        if (result.data.code === 401 ||
            (typeof response.msg === 'string' && 
             response.msg.toLowerCase().includes('token'))) {
            handleUnauthorized();
            return Promise.reject(result.data);
        }

        //操作失败
        ElMessage.error(result.data.msg ? result.data.msg : '服务异常');

        //异步操作的状态转换为失败
        return Promise.reject(result.data);
    },

    //失败的回调
    err => {
        //判断响应状态码，若为401，则说明未登录，提示请登录，并跳转到登录页面
        if (err.response.status === 401) {
            handleUnauthorized();
        } else {
            const errorMsg = err.response?.data?.msg || '服务异常';
            ElMessage.error(errorMsg);
        }

        //异步的状态转化成失败的状态
        return Promise.reject(err);
    }
)

// 添加防抖机制变量
let lastUnauthorizedAlert = 0; // 上一次提示的时间戳
const ALERT_INTERVAL = 2000; // 2秒内不重复提示

// 提取未登录处理逻辑为独立函数
function handleUnauthorized() {

    const now = Date.now();
    // 如果上次提示时间未超过2秒，则跳过
    if (now - lastUnauthorizedAlert < ALERT_INTERVAL) return;

    lastUnauthorizedAlert = now; // 更新最后提示时间

    // 清除无效token
    const tokenStore = useTokenStore();
    tokenStore.setToken('');

    // 提示并跳转
    ElMessage.warning('登录已过期，请重新登录');

    // 重定向到登录页（带当前路由参数）
    router.push({
        path: '/login',
        query: {
            redirect: router.currentRoute.value.fullPath
        }
    });
}

//把请求的实例instance导出,供其他地方调用
export default instance;